package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersCancelDTO;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.*;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private WebSocketServer webSocketServer;

    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        //异常情况的处理（收货地址为空、超出配送范围、购物车为空）
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        Long userId = BaseContext.getCurrentId();
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.getByUserId(userId);
        if (shoppingCarts == null || shoppingCarts.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO,orders);
        orders.setUserId(userId);
        orders.setUserName(userMapper.getUserNameById(userId));
        orders.setAddress(addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getProvinceName()+addressBook.getDetail());
        orders.setPhone(addressBook.getPhone());
        orders.setConsignee(addressBook.getConsignee());
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setOrderTime(LocalDateTime.now());
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setPayStatus(Orders.UN_PAID);
        orders.setUserName(userMapper.getUserNameById(userId));

        orderMapper.insert(orders);

        List<OrderDetail> orderDetails = new ArrayList<>();
        for (ShoppingCart shoppingCart : shoppingCarts) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(shoppingCart,orderDetail);
            orderDetail.setOrderId(orders.getId());
            orderDetails.add(orderDetail);
        }
        orderDetailMapper.insertBatch(orderDetails);

        shoppingCartMapper.deleteAllByUserId(userId);

        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(orders.getId())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .orderNumber(orders.getNumber())
                .build();
        return orderSubmitVO;
    }

    @Override
    public OrderPaymentVO payMent(OrdersPaymentDTO ordersPaymentDTO) {
        int check = orderMapper.updateCheckOutTime(ordersPaymentDTO, LocalDateTime.now());
        Long orderId = orderMapper.getIdByNumber(ordersPaymentDTO.getOrderNumber());
        Map map = new HashMap<>();
        if (check == 1){
            map.put("type",1);
            map.put("ordersId",orderId);
            map.put("content", "订单号：" + ordersPaymentDTO.getOrderNumber());
        }
        webSocketServer.sendToAllClient(JSON.toJSONString(map));

        OrderPaymentVO orderPaymentVO = new OrderPaymentVO();
        return orderPaymentVO;
    }

    @Override
    public PageResult pageQuery(OrdersPageQueryDTO pageQueryDTO){
        PageHelper.startPage(pageQueryDTO.getPage(),pageQueryDTO.getPageSize());
        Page<OrderVO> orderVOPage = orderMapper.query(pageQueryDTO);
        orderVOPage.forEach(orderVO -> {
            OrdersDetailVO ordersDetailVO = orderDetailMapper.getDetailsByOrderId(orderVO.getId());
            if (ordersDetailVO != null) {
                orderVO.setOrderDishes(ordersDetailVO.getDetailDish());
                orderVO.setOrderDetailList(orderDetailMapper.getByOrderId(orderVO.getId()));
            }
        });
        return new PageResult(orderVOPage.getTotal(),orderVOPage.getResult());
    }

//    @Override
//    public PageResult pageQuery(OrdersPageQueryDTO pageQueryDTO) {
//        PageHelper.startPage(pageQueryDTO.getPage(),pageQueryDTO.getPageSize());
//        Page<OrdersPageVO> ordersPageVOPage = orderMapper.query(pageQueryDTO);
//        ordersPageVOPage.forEach(ordersPageVO -> {
//            OrdersDetailVO ordersDetailVO = orderDetailMapper.getDetailsByOrderId(ordersPageVO.getId());
//            ordersPageVO.setOrderDishes(ordersDetailVO.getDetailDish());
//        });
//        return new PageResult(ordersPageVOPage.getTotal(),ordersPageVOPage.getResult());
//    }

    @Override
    public OrderStatisticsVO statistics() {
        OrderStatisticsVO orderStatisticsVO = orderMapper.statistics();
        return orderStatisticsVO;
    }

    @Override
    public void confirm(Long id) {
        orderMapper.updateStatusById(id,3);
    }

    @Override
    public void delivery(Long id) {
        orderMapper.updateStatusById(id,4);
    }

    @Override
    public void complete(Long id) {
        orderMapper.completeById(id);
    }

    @Override
    public void cancel(OrdersCancelDTO dto) {
        orderMapper.cancel(dto);
    }

    @Override
    public OrderVO details(Long id) {
        OrderVO orderVO = orderMapper.getById(id);
        orderVO.setOrderDetailList(orderDetailMapper.getByOrderId(orderVO.getId()));
        return orderVO;
    }

    @Override
    public void reminder(Long id) {
        OrderVO orderVO = orderMapper.getById(id);
        if (orderVO == null ){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        Map map = new HashMap();
        map.put("type", 2);//2代表用户催单
        map.put("orderId", id);
        map.put("content", "订单号：" + orderVO.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }
}
